﻿using System;
using System.Linq;
using System.Collections.Generic;

using Microsoft.Xna.Framework;

using Ah.Testudin.Engine.Actors.Components;

namespace Ah.Testudin.Engine.Actors
{
    public class Actor : IDisposable
    {
        #region Private Member Variables

        private IDictionary<Type, IActorComponent> _actorComponentMap;

        #endregion

        #region Properties

        public ActorId Id { get; private set; }

        #endregion

        #region Constructors

        public Actor(ActorId id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }

            this.Id = id;

            _actorComponentMap = new Dictionary<Type, IActorComponent>();
        }

        #endregion

        #region Methods

        public void SetComponent<T>(IActorComponent component) where T : IActorComponent
        {
            if (_actorComponentMap.Where(
                x => x.Key == typeof(T)).Any())
            {
                _actorComponentMap[typeof(T)] = component;
            }
            else
            {
                _actorComponentMap.Add(
                    typeof(T),
                    component);
            }
        }

        public T GetComponent<T>() where T : IActorComponent
        {
            IActorComponent component = _actorComponentMap.SingleOrDefault(
                x => x.Key == typeof(T)).Value;

            if (component != null)
            {
                return (T)component;
            }

            return default(T);
        }

        #endregion

        #region IDisposable

        public void Dispose()
        {
            foreach (IActorComponent currentActorComponent in _actorComponentMap.Select(x => x.Value))
            {
                currentActorComponent.Dispose();
            }

            _actorComponentMap.Clear();
        }

        #endregion
    }
}
